import java.net.*;
import java.util.*;
import java.util.Map.Entry;
import external.*;
public class Players {
	private static volatile Map<Socket, PlayerInfo> playersMap=new HashMap<Socket, PlayerInfo>();
	private static int amountOfRooms;
	
	public static void Init()
	{
//		playersMap = new HashMap<Socket, PlayerInfo>();
		amountOfRooms = 1;
		RoadGenerator.Init();
	}
	
	public synchronized static void RegisterPlayer(Socket socket)
	{
		playersMap.put(socket, new PlayerInfo());
		SocketWriter.SendMessage(new Message(Message.Type.ViewRooms, Players.NumberOfPlayersInRooms()), socket);
	}
	
	public synchronized static void AssignPlayerToRoom(Socket socket, int roomNumber)
	{
		playersMap.get(socket).room=roomNumber;
		if(roomNumber==amountOfRooms) amountOfRooms+=1;
		SocketWriter.SendMessage(new Message(Message.Type.Road, RoadGenerator.RoadForRoom(roomNumber)), socket);
		if(NumberOfPlayersInRoom(roomNumber)==GameParameters.amountOfPlayers)
		{
			for(Entry<Socket,PlayerInfo> entry:playersMap.entrySet())
			{
				if(entry.getValue().room==roomNumber) 
					SocketWriter.SendMessage(new Message(Message.Type.StartGame, null), entry.getKey());
			}
			
		}
	}
	
	public static int[] NumberOfPlayersInRooms()
	{
		int[] result = new int[amountOfRooms];
		for(int i=0;i<amountOfRooms;i++)
			result[i]=0;
		for(PlayerInfo playerInfo:playersMap.values())
		{
			if(playerInfo.room!=0) result[playerInfo.room-1]++;
		}
		return result;
	}
	
	public static int NumberOfPlayersInRoom(int roomNumber)
	{
		return NumberOfPlayersInRooms()[roomNumber-1];
	}
	
	public static void ModifyPlayerState(Socket socket, Player playerState)
	{
		playersMap.get(socket).playerState=new Player(playerState);
		SocketWriter.SendMessage(new Message(Message.Type.playersStates, RoommateState(socket)), socket);
	}
	
	public static synchronized Player[] RoommateState(Socket socket)
	{
		Player[] result = new Player[GameParameters.amountOfPlayers-1];
		PlayerInfo selfInfo = playersMap.get(socket);
		int i=0;
		for(PlayerInfo playerInfo:playersMap.values())
		{
			if(playerInfo.room==selfInfo.room && !selfInfo.playerState.equals(playerInfo.playerState))
			{
				result[i]= new Player(playerInfo.playerState);
				i++;
			}
		}
		return result;
	}
}
